package helperF

import (
	"errors"
	"github.com/jinzhu/copier"
	"reflect"
	"time"
)

// TimeNowStr 当前时间串
func TimeNowStr() string {
	return TimeToTimeStr(time.Now())
}

// DayZero 获取某日零点。+1表示明天零点，-1表示昨天零点
func DayZero(n int) time.Time {
	now := time.Now()
	year, month, day := now.Date()
	t := time.Date(year, month, day, 0, 0, 0, 0, now.Location())
	if n != 0 {
		t = t.AddDate(0, 0, n)
	}
	return t
}

// TimeToTimeStr time.Time->时间串，返回时间的字符串形式(中国时区、东八区)
// 默认使用2006-01-02 15:04:05格式化
func TimeToTimeStr(t time.Time, fmts ...string) string {
	fmt := "2006-01-02 15:04:05"
	if len(fmts) > 0 {
		fmt = fmts[0]
	}
	tz, _ := time.LoadLocation("Asia/Shanghai")
	return t.In(tz).Format(fmt)
}

// TsToTimeStr 时间戳->时间串，返回时间的字符串形式(中国时区、东八区)
//
// 默认使用2006-01-02 15:04:05格式化
//
// 注：时间戳使用int64
func TsToTimeStr(ts int64, fmts ...string) string {
	fmt := "2006-01-02 15:04:05"
	if len(fmts) > 0 {
		fmt = fmts[0]
	}
	if ts <= 0 {
		return ""
	}
	t := time.Unix(ts, 0)
	tz, _ := time.LoadLocation("Asia/Shanghai")
	return t.In(tz).Format(fmt)
}

// TsToTime 时间戳->time.Time，返回给DB的时间格式(中国时区、东八区)
//
// 注：时间戳使用int64
func TsToTime(ts int64) time.Time {
	return time.Unix(ts, 0)
}

// TsToTimePtr 时间戳->*time.Time，返回给DB的时间格式(中国时区、东八区)
func TsToTimePtr(ts int64) *time.Time {
	if ts <= 0 {
		return nil
	}
	t := time.Unix(ts, 0)
	if t.IsZero() {
		return nil
	}
	return &t
}

// TimeToPbTs 用于pb传输的时间戳
//
// 注：时间戳使用int64
func TimeToPbTs(t *time.Time) int64 {
	if t == nil || t.IsZero() {
		return 0
	}
	return t.Unix()
}

// CopierConverterTsToTime 时间戳->time.Time，用于copier包复制时自动时间类型转换
//
// 注：时间戳使用int64
func CopierConverterTsToTime() []copier.TypeConverter {
	return []copier.TypeConverter{
		{
			SrcType: int64(0),
			DstType: time.Time{},
			Fn: func(src interface{}) (interface{}, error) {
				ts, ok := src.(int64)
				if !ok {
					return nil, errors.New("src type not matching")
				}

				if ts <= 0 {
					return nil, nil
				}

				return time.Unix(ts, 0), nil
			},
		},
	}
}

// CopierConverterTimeToTs time.Time->时间戳，用于copier包复制时自动时间类型转换
//
// 注：时间戳使用int64
func CopierConverterTimeToTs() []copier.TypeConverter {
	return []copier.TypeConverter{
		{
			SrcType: time.Time{},
			DstType: int64(0),
			Fn: func(src interface{}) (interface{}, error) {
				s, ok := src.(time.Time)
				if !ok {
					return nil, errors.New("src type not matching")
				}

				if s.IsZero() {
					return int64(0), nil
				}

				return s.Unix(), nil
			},
		},
	}
}

// CopierConverterTimeToStr time.Time->时间字符串，用于copier包复制时自动时间类型转换
// 默认使用2006-01-02 15:04:05格式化
func CopierConverterTimeToStr(fmts ...string) []copier.TypeConverter {
	fmt := "2006-01-02 15:04:05"
	if len(fmts) > 0 {
		fmt = fmts[0]
	}
	return []copier.TypeConverter{
		{
			SrcType: time.Time{},
			DstType: string(""),
			Fn: func(src interface{}) (interface{}, error) {
				refval := reflect.ValueOf(src)
				filedName := refval.Type().Field(0).Name
				_ = filedName
				s, ok := src.(time.Time)
				if !ok {
					return nil, errors.New("src type not matching")
				}

				tz, _ := time.LoadLocation("Asia/Shanghai")
				return s.In(tz).Format(fmt), nil
			},
		},
	}
}
